/**
 *@Project:SocialTag
 *@Package:process
 *@Name:TagClustering.java
 *@Author:yexijiang
 *@Date:Jul 6, 2008
 *@Decription:
 */
package process;

import java.util.Vector;

import process.models.KMeans;

import util.Timer;

import data.Distance;
import data.EuclideanDistance;
import data.SimilaritySet;

/**
 * Clustering the tag.
 */
public class TagClustering 
{

	private SimilaritySet m_Sets[];
	private int m_Dimension;
	private Vector<String> m_SetsLabels[];
	private int m_NumOfClusters;
	private Vector<Double> m_ClusterCenters[][];	//a center vector for each cluster for each set
	private Vector<String> m_TagCluster[][];	//	each cluster store the name of the tag
	private Distance m_DistFunc;
	private int m_Sequence[];
	
	public TagClustering(int sequence[], int numOfClusters, int numOfCandidateTags, int recordsForEachTag)
	{
		m_Sequence = sequence;
		m_NumOfClusters = numOfClusters;
		m_Dimension = sequence.length;
		PreProcess preProcess = new PreProcess(numOfCandidateTags, sequence, recordsForEachTag);
		m_Sets = preProcess.preProcess();
		m_SetsLabels = new Vector[m_Sets.length];	//	a label vector for each set
		m_ClusterCenters = new Vector[m_Sets.length][m_NumOfClusters];	//	a center vector for each set
		m_TagCluster = new Vector[m_Sets.length][m_NumOfClusters];
		m_DistFunc = new EuclideanDistance();
		//System.out.println(preProcess);
	}
	
	public Vector<String>[][] doClustering()
	{
		System.out.println("Begin K-means clustering.");
		long startClustering = Timer.startRecord();
		/*for(int i = 0; i < m_Sets.length; ++i)	//	add the target tag to each set
		{
			System.out.println("\n" + m_Sets[i].size());
			String label = m_Sets[i].getTargetTag();
			Vector<Double> v = new Vector<Double>();
			for(int j = 0; j < m_Dimension; ++j)
			{
				v.add(1.00);
			}
			m_Sets[i].addRecord(label, v);
			System.out.println(m_Sets[i].size());
		}*/
		
		for(int i = 0; i < m_TagCluster.length; ++i)
		{
			for(int j = 0; j < m_TagCluster[i].length; ++j)
			{
				m_TagCluster[i][j] = new Vector<String>();
			}
		}
		
		for(int i = 0; i < m_Sets.length; ++i)
		{
			m_SetsLabels[i] = m_Sets[i].getKeys();
			KMeans kmeans = new KMeans(m_Sequence, m_NumOfClusters, m_Sets[i], m_SetsLabels[i], m_DistFunc);
			m_TagCluster[i] = kmeans.doClustering();
			//doSingleSetClustering(i);
		}
		long endClustering = Timer.endRecord(startClustering);
		System.out.println("The time K-means clustering use is:" + endClustering);
		return m_TagCluster;
	}
	
	public Vector<String> getTargetTags()
	{
		Vector<String> targetTags = new Vector<String>();
		for(int i = 0; i < m_Sets.length; ++i)
		{
			targetTags.add(m_Sets[i].getTargetTag());
		}
		return targetTags;
	}

	public String toString()
	{
		String msg = new String();
		
		for(int setNo = 0; setNo < m_Sets.length; ++setNo)
		{
			msg += "\n\nFor tag '" + m_Sets[setNo].getTargetTag() + "':";
			for(int i = 0; i < m_TagCluster[setNo].length; ++i)
			{
				msg += "\nFor cluster " + i + ", size:" + m_TagCluster[setNo][i].size() + "\n";
				for(int j = 0; j < m_TagCluster[setNo][i].size(); ++j)
				{
					msg += m_TagCluster[setNo][i].get(j) + "\t";
				}
			}
		}
		
		return msg;
	}
	
	public static void main(String[] args)
	{
		int sequence[] = {1,2,3,4,5,6,7,8};
		int numOfCluster = 5;
		int numOfCandidateTags = 3;
		int recordsForEachTag = 30;
		
		TagClustering clustering = new TagClustering(sequence, numOfCluster, numOfCandidateTags, recordsForEachTag);
		clustering.doClustering();
		System.out.println(clustering);
		/*
		//	Experiment to test dimension 1-8
		for(int i = 1; i < 9; ++i)
		{
			int seq[] = new int[i];
			System.out.println("\nFor dimension " + i + ":");
			for(int j = 1; j <= i; ++j)
			{
				seq[j - 1] = j;
			}
			TagClustering clustering = new TagClustering(seq, numOfCluster, numOfCandidateTags, recordsForEachTag);
			clustering.doClustering();
			System.out.println(clustering);
		}*/
	}
	
}
